home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pine / pine3.07 / pico / spell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-23  |  6.1 KB  |  257 lines

  1. /*
  2.  * Program:    spell.c
  3.  *
  4.  * Author:    Michael Seibel
  5.  *        Networks and Distributed Computing
  6.  *        Computing & Communications
  7.  *        University of Washington
  8.  *        Administration Building, AG-44
  9.  *        Seattle, WA  98195
  10.  *        Internet: <author's email address>@CAC.Washington.EDU
  11.  *
  12.  * Date:    30 July 1991
  13.  * Last Edited:    6 Jan 1992
  14.  *
  15.  * Copyright 1991 by the University of Washington
  16.  *
  17.  *  Permission to use, copy, modify, and distribute this software and its
  18.  * documentation for any purpose and without fee is hereby granted, provided
  19.  * that the above copyright notice appears in all copies and that both the
  20.  * above copyright notice and this permission notice appear in supporting
  21.  * documentation, and that the name of the University of Washington not be
  22.  * used in advertising or publicity pertaining to distribution of the software
  23.  * without specific, written prior permission.  This software is made
  24.  * available "as is", and
  25.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  26.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  27.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  28.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  29.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  30.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  31.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  32.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  33.  *
  34.  */
  35.  
  36. #include <stdio.h>
  37. #include "osdep.h"
  38. #include "estruct.h"
  39. #ifdef    SPELLER
  40. #include "edef.h"
  41. #include "pico.h"
  42.  
  43.  
  44. #define  NSHLINES  12
  45.  
  46. static char *spellhelp[] = {
  47.   "Spell Check Help",
  48.   " ",
  49.   "\tThe spell checker examines all words in the text.  It then",
  50.   "\toffers each misspelled word for correction while simultaneously",
  51.   "\thighlighting it in the text.  To leave a word unchanged simply",
  52.   "~\thit ~R~e~t~u~r~n at the edit prompt.  If a word has been corrected,",
  53.   "\teach occurrence of the incorrect word is offered for replacement.",
  54.   " ",
  55.   "~\tSpell checking can be canceled at any time by typing ~^~C (~F~3)",
  56.   "\tafter exiting help.",
  57.   " ",
  58.   "End of Spell Check Help",
  59.   " ",
  60.   NULL
  61. };
  62.  
  63.  
  64.  
  65. /*
  66.  * spell() - check for potentially missspelled words and offer them for
  67.  *           correction
  68.  */
  69. spell(f, n)
  70. {
  71.     int    status, next, khelp = 0, ret;
  72.     FILE   *p;
  73.     char   *b, *sp, *fn;
  74.     char   wb[NLINE], cb[NLINE];
  75.     char   *writetmp();
  76.     FILE   *P_open();
  77.  
  78.     setmark(0, 1);
  79.     emlwrite("Checking spelling...");         /* greetings */
  80.  
  81.     if((fn = writetmp(0, 0)) == NULL){
  82.     emlwrite("Can't write temp file for spell checker");
  83.     return(-1);
  84.     }
  85.     if((sp = (char *)getenv("SPELL")) == NULL)
  86.       sp = SPELLER;
  87.     sprintf(s, "( %s ) < %s", sp, fn);
  88.  
  89.     if((p=P_open(s)) == NULL){            /* read output from command */
  90.     unlink(fn);
  91.     emlwrite("Can't fork spell checker");
  92.     return(-1);
  93.     }
  94.  
  95.     khelp = 0;
  96.     ret = 1;
  97.     while(fgets(wb, NLINE, p) != NULL && ret){
  98.     if((b = (char *)strchr(wb,'\n')) != NULL)
  99.       *b = '\0';
  100.     strcpy(cb, wb);
  101.  
  102.     gotobob(0, 1);
  103.  
  104.     if(Pmaster == NULL)
  105.       sgarbk = FALSE;
  106.  
  107.     status = TRUE;
  108.     next = 1;
  109.  
  110.     while(status){
  111.         if(!khelp++)            /* not too early */
  112.           wkeyhelp("GC0000000000", "Get Help,Cancel");
  113.  
  114.         if(next++)
  115.           if(movetoword(wb) != TRUE)
  116.         break;
  117.  
  118.         update();
  119.         (*term.t_rev)(1);
  120.         pputs(wb);                /* highlight word */
  121.         (*term.t_rev)(0);
  122.  
  123.         if(strcmp(cb, wb)){
  124.         sprintf(s, "Replace %s with %s", wb, cb);
  125.         status=mlyesno(s, TRUE);
  126.         }
  127.         else
  128.           status=mlreplyd("Edit a replacement: ", cb, NLINE, QDEFLT);
  129.  
  130.  
  131.         curwp->w_flag |= WFMOVE;        /* put cursor back */
  132.         update();
  133.         pputs(wb);                /* un-highlight */
  134.  
  135.         switch(status){
  136.           case TRUE:
  137.         chword(wb, cb);            /* correct word    */
  138.           case FALSE:
  139.         update();            /* place cursor */
  140.         break;
  141.           case ABORT:
  142.         emlwrite("Spell Checking Aborted", NULL);
  143.         ret = FALSE;
  144.         status = FALSE;
  145.         break;
  146.           case HELPCH:
  147.         if(Pmaster)
  148.           (*Pmaster->helper)(spellhelp, "Help with Spelling Checker", 1);
  149.         else
  150.           pico_help(spellhelp, "Help with Spelling Checker", 1);
  151.           case (CTRL|'L'):
  152.         next = 0;            /* don't get next word */
  153.         khelp = 0;            /* key help has changed */
  154.         sgarbf = TRUE;            /* repaint full screen */
  155.         update();
  156.         status = TRUE;
  157.         continue;
  158.           default:
  159.         emlwrite("Huh?");        /* shouldn't get here, but.. */
  160.         status = TRUE;
  161.         sleep(1);
  162.         break;
  163.         }
  164.         forwword(0, 1);            /* goto next word */
  165.     }
  166.     }
  167.     P_close(p);                    /* clean up */
  168.     unlink(fn);
  169.     swapmark(0, 1);
  170.     curwp->w_flag |= WFHARD|WFMODE;
  171.  
  172.     if(Pmaster == NULL)
  173.       sgarbk = TRUE;
  174.  
  175.     if(ret)
  176.       emlwrite("Done checking spelling");
  177.     return(ret);
  178. }
  179.  
  180.  
  181.  
  182.  
  183. /* 
  184.  * chword() - change the given word, wp, pointed to by the curwp->w_dot 
  185.  *            pointers to the word in cb
  186.  */
  187. chword(wb, cb)
  188. char *wb;                    /* word buffer */
  189. char *cb;                    /* changed buffer */
  190. {
  191.     ldelete(strlen(wb), 0);            /* not saved in kill buffer */
  192.     while(*cb != '\0')
  193.       linsert(1, *cb++);
  194.  
  195.     curwp->w_flag |= WFEDIT;
  196. }
  197.  
  198.  
  199.  
  200.  
  201. /* 
  202.  * movetoword() - move to the first occurance of the word w
  203.  *
  204.  *    returns:
  205.  *        TRUE upon success
  206.  *        FALSE otherwise
  207.  */
  208. movetoword(w)
  209. char *w;
  210. {
  211.     int      i;
  212.     int      ret  = FALSE;
  213.     int         olddoto;
  214.     LINE     *olddotp;
  215.     register int   off;                /* curwp offset */
  216.     register LINE *lp;                /* curwp line   */
  217.  
  218.     olddoto = curwp->w_doto;            /* save where we are */
  219.     olddotp = curwp->w_dotp;
  220.  
  221.     curwp->w_bufp->b_mode |= MDEXACT;        /* case sensitive */
  222.     while(forscan(&i, w, 1) == TRUE){
  223.     if(i)
  224.       break;                /* wrap NOT allowed! */
  225.  
  226.     lp  = curwp->w_dotp;            /* for convenience */
  227.     off = curwp->w_doto;
  228.  
  229.     /*
  230.      * We want to minimize the number of substrings that we report
  231.      * as matching a misspelled word...
  232.      */
  233.     if(off == 0 || !isalpha(lgetc(lp, off - 1))){
  234.         off += strlen(w);
  235.         if((!isalpha(lgetc(lp, off)) || off == llength(lp)) 
  236.            && lgetc(lp, 0) != '>'){
  237.         ret = TRUE;
  238.         break;
  239.         }
  240.     }
  241.  
  242.     forwchar(0, 1);                /* move on... */
  243.  
  244.     }
  245.     curwp->w_bufp->b_mode ^= MDEXACT;        /* case insensitive */
  246.  
  247.     if(ret == FALSE){
  248.     curwp->w_dotp = olddotp;
  249.     curwp->w_doto = olddoto;
  250.     }
  251.     else
  252.       curwp->w_flag |= WFHARD;
  253.  
  254.     return(ret);
  255. }
  256. #endif    /* SPELLER */
  257.